﻿using System.Dynamic;
using System.Reflection;

namespace App_1.ResponseType.DataShaping
{
    /// <summary>
    /// 数据构型扩展类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class DataShaper<T>
    {
        //必须要展示的字段
        private readonly List<PropertyInfo> _requiredProperties = new List<PropertyInfo>();

        public DataShaper(string? fieldsString)
        {
            //获取对象的字段
            var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

            //如果构型字段为空，则表示显示所有字段
            if (string.IsNullOrWhiteSpace(fieldsString))
            {
                _requiredProperties = properties.ToList();
            }
            else
            {
                // account,accountType

                //逗号拆分，忽略空格
                var fields = fieldsString.Split(',', StringSplitOptions.RemoveEmptyEntries);
                foreach (var field in fields)
                {
                    //如果包含在要构型的字段中则添加进要展示的字段
                    var property = properties.FirstOrDefault(pi =>
                        pi.Name.Equals(field.Trim(), StringComparison.InvariantCultureIgnoreCase));
                    if (property == null)
                        continue;
                    _requiredProperties.Add(property);
                }
            }
        }

        public ExpandoObject FetchData(T sourceData)
        {
            //ExpandoObject 对象在 .NET 中主要用于支持动态编程概念，允许在运行时动态地添加、删除或修改其成员（如属性和方法）。该对象实现自 IDynamicMetaObjectProvider 接口，这意味着它能在支持动态语言运行时（DLR）互操作性模型的语言之间共享实例。
            var shapedObject = new ExpandoObject();

            foreach (var property in _requiredProperties)
            {
                var objectPropertyValue = property.GetValue(sourceData);
                shapedObject.TryAdd(property.Name, objectPropertyValue);
            }

            return shapedObject;
        }

        public IEnumerable<ExpandoObject> FetchData(IEnumerable<T> sourceData)
        {
            var shapedData = new List<ExpandoObject>();

            foreach (var item in sourceData)
            {
                var shapedObject = FetchData(item);
                shapedData.Add(shapedObject);
            }

            return shapedData;
        }

    }

}
